package com.shuqing.download.engine.distribute;

import com.shuqing.download.engine.DownLoadTaskDto;
import com.shuqing.download.engine.config.EngineConfig;
import com.shuqing.download.engine.constants.TaskStatusEnum;
import com.shuqing.download.engine.distribute.dispatch.TaskContext;
import com.shuqing.download.engine.distribute.dispatch.monitor.MonitorLeader;
import com.shuqing.download.engine.distribute.dispatch.assemble.DefaultAssembleDispatch;
import com.shuqing.download.engine.distribute.dispatch.upload.DefaultUploadDispatch;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author wangshuqing
 * @date 2023/2/12 14:55
 */
@Component
@Slf4j
public class DefaultDistributeHandler implements DistributeHandler{

    @Autowired
    protected EngineConfig engineConfig;
    @Autowired
    private DefaultAssembleDispatch assembleDispatch;
    @Autowired
    private DefaultUploadDispatch uploadDispatch;
    @Autowired
    private MonitorLeader monitorLeader;

    @Override
    public  Boolean accept() {
        //同步代码块获取可活动任务数
        synchronized (DefaultDistributeHandler.class){
            int enableRunCount=engineConfig.getMaxTaskCountAtom().get();
            if(enableRunCount>0){
                engineConfig.getMaxTaskCountAtom().addAndGet(-1);
                return true;
            }
            return false;
        }
    }

    @Override
    public int possibleMoreAccept() {
        synchronized (DefaultDistributeHandler.class){
            int maxEnableCount=engineConfig.getMaxTaskCountAtom().get();
            if(maxEnableCount>0){
                engineConfig.getMaxTaskCountAtom().addAndGet(-maxEnableCount);
            }
            return maxEnableCount;
        }
    }


    @Override
    public void process(DownLoadTaskDto taskDto) {
        TaskContext context=new TaskContext(taskDto);
        DownLoadTaskDto downLoadTaskDto= context.getTask();
        try{
            monitorLeader.assignSuccessNotify(context,TaskStatusEnum.RUNNING);
            Boolean success=assembleDispatch.dispatch(context,downLoadTaskDto.getActuator());
            if(success){
                uploadDispatch.dispatch(context,downLoadTaskDto.getUploadActuator());
            }else{
                log.info("下载任务{},未执行数据组装",downLoadTaskDto.getId());
            }
            monitorLeader.assignSuccessNotify(context,TaskStatusEnum.SUCCESS);
        }catch (Exception ex){
            log.error("下载任务{},失败",downLoadTaskDto.getId(),ex);
            monitorLeader.assignNotify(context,TaskStatusEnum.FAIL,ex);
        }finally {
            //归回手持的任务许可
            backOneAccept();
        }
    }


    private void backAccept(int count){
        int total=engineConfig.getMaxTaskCountAtom().addAndGet(count);
        log.info("可派发任务数：{}",total);
    }

    @Override
    public void backOneAccept(){
        backAccept(1);
    }

}
